﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace NEM
{
    [Serializable]
    public class Log
    {

        #region Private Variables / Constants

        #endregion

        #region Constructors
        public Log()
        {

        }
        #endregion

        #region Properties

        private bool _Enabled = Globals.ApplicationSettings.EnableLog;
        [Category("Settings")]
        [DisplayName("Enable")]
        [Description("Enable Logging.")]
        public bool Enable
        {
            get { return _Enabled; }
            set { _Enabled = value; }
        }

        private String _FolderPath = Globals.ApplicationSettings.LogFolderPath;
        [Category("Settings")]
        [DisplayName("Folder Path")]
        [Description("Path of the Folder where the log should be written to.")]
        public String FolderPath
        {
            get
            {
                if ((_FolderPath == string.Empty) || (Directory.Exists(_FolderPath) == false))
                {
                    _FolderPath = Path.GetDirectoryName(Application.ExecutablePath);
                }                

                if (_FolderPath.EndsWith("\\") == false)
                {
                    _FolderPath += "\\";
                }

                return _FolderPath;
            }
            set {
                    if ((value == string.Empty) || (Directory.Exists(value) == false))
                    {
                        _FolderPath = Path.GetDirectoryName(Application.ExecutablePath);
                    }
                    else
                    {
                        _FolderPath = value;
                    }

                    if (_FolderPath.EndsWith("\\") == false)
                    {
                        _FolderPath += "\\";
                    }
                }
        }

        private String _FileName = Globals.ApplicationSettings.LogFileName;
        [Category("Settings")]
        [DisplayName("File Name")]
        [Description("The name of the log file.")]
        public String FileName
        {
            get
            {
                if ((_FileName == string.Empty) || (IsValidFilename(_FileName) == false))
                {
                    _FileName = "NEM_LOG.LOG";
                }
                return _FileName;
            }
            set {
                    if ((value == string.Empty) || (IsValidFilename(value) == false))
                    {
                        _FileName = "NEM_LOG.LOG";
                    }
                    else
                    {
                        _FileName = value;
                    }

                }
        }
        #endregion

        #region Methods

        /// <summary>
        /// Log any messages from the Application
        /// </summary>
        /// <param name="message"></param>
        public bool LogMessage(String pMessage, Exception pEx = null)
        {
            bool lvResult = false;

            if (!Globals.ApplicationSettings.EnableLog) return false;

            for (int lvRetryCounter = 0; lvRetryCounter < 3; lvRetryCounter++)
            {
                try
                {
                    // Log message to default log file.
                    StreamWriter lvStreamWriter = new StreamWriter(Globals.Logger.FolderPath + Globals.Logger.FileName, true);

                    lvStreamWriter.AutoFlush = false;
                    lvStreamWriter.WriteLine(string.Format(Environment.NewLine + "TimeStamp: {0}Message: {1}Exception Message: {2}",
                                                            DateTime.Now.ToString() + Environment.NewLine,
                                                            pMessage + Environment.NewLine,
                                                            pEx == null ? "" : pEx.Message + Environment.NewLine)
                                                          );
                    lvStreamWriter.Flush();
                    lvStreamWriter.Close();

                    lvResult = true;
                }
                catch (Exception ex)
                {
                    Debug.Print(ex.Message);
                }

                if (lvResult == true)
                {
                    break;
                }
                else
                {
                    //Sleep Maybe System is busy with file or it is locked.
                    Thread.Sleep(100);
                }
            }

            return lvResult;
        }

        private bool IsValidFilename(string testName)
        {
            Regex containsABadCharacter = new Regex("[" + Regex.Escape(System.IO.Path.GetInvalidFileNameChars().ToString()) + "]");
            if (containsABadCharacter.IsMatch(testName) )
            { 
                return false; 
            };

            return true;
        }

        #endregion

    } 
}
